Technical Q&A QA1123
Getting List of All Processes on Mac OS X


Q: Mac OS X è„ÇÃÇ∑Ç◊ǃÇÃÉvÉçÉZÉXÇÃÉäÉXÉgÇéÊìæÇ∑ÇÈÇ…ÇÕÇ«ÇÃÇÊǧDžÇ∑ÇÍÇŒÇÊÇ¢ÇÃÇ≈ǵÇÂǧǩÅH

A: ǪÇÍÇÕÅAÉvÉçÉZÉXÇÇ«ÇÃÇÊǧDžíËã`Ç∑ÇÈǩDžÇÊÇËÇ‹Ç∑ÅBé¿çsíÜÇÃÉAÉvÉäÉPÅ[ÉVÉáÉìÇÃÉäÉXÉgÇ™ïKóvÇ»ÇÁÇŒÅACarbon Process Manager ÉãÅ[É`ÉìÅAGetNextProcess ÇégǢNjÇ∑ÅBDZÇÃÉãÅ[É`ÉìÇÕÅACarbonÅACocoaÅAÇ®ÇÊÇ— Classic ÇÃä¬ã´Ç≈é¿çsÇ≥ÇÍǃǢÇÈLJÇÃÇä‹ÇfiÅAÇ∑Ç◊ǃÇÃÉAÉvÉäÉPÅ[ÉVÉáÉìÉvÉçÉZÉXÇÃÉäÉXÉgÇï‘ǵNjÇ∑ÅBǵǩǵÅADZÇÍÇÕÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ǻǢÅiÉfÅ[ÉÇÉìÅjÉvÉçÉZÉXÇÃÉäÉXÉgÇÕï‘ǵNjÇπÇÒÅB

íçà”ÅF
GetNextProcess Ç…ä÷ǵǃLJǧ 1 Ǭíçà”Ç∑Ç◊ǴDZÇΔÇÕÅACarbon ÇΔÉäÉìÉNÇ∑ÇÈïKóvǙdžÇÈì_Ç≈Ç∑ÅBÇΩÇæÇµÅAÉvÉçÉOÉâÉÄÇ…ÇÊǡǃÇÕÅiBSD ÇÃÉfÅ[ÉÇÉìÉvÉçÉZÉXǻǫÅjÅADZÇÍÇÕïsâ¬î\Ç≈Ç∑ÅB

BSD Çà sysctl ÉãÅ[É`ÉìÇégǶnjÅAÉfÅ[ÉÇÉìÉvÉçÉZÉXÇä‹ÇfiÇ∑Ç◊ǃÇà BSD ÉvÉçÉZÉXÇÃÉäÉXÉgÇéÊìæÇ≈Ç´Ç‹Ç∑ÅBDZÇÍÇé¿çsÇ∑ÇÈÉRÅ[ÉhÇÉäÉXÉg 1 Ç…é¶ÇµÇ‹Ç∑ÅB DZÇÃÉRÅ[ÉhÇégópÇ∑ÇÈÇΔÇ´Ç…ÇÕÅAéüÇÃDZÇΔÇ…íçà”ÇµÇ»ÇØÇÍnjǻÇËÇ‹ÇπÇÒÅB

  • ï‘Ç≥ÇÍÇÈ kinfo_proc ç\ë¢ëÃÇ…ÇÕÅAÉvÉçÉZÉX ID Åikp_proc.p_pid Ç…ÅjÇΔÉvÉçÉZÉXñºÅikp_proc.p_comm Ç…ÅjÇä‹ÇflÅAÉvÉçÉZÉXÇ…ä÷Ç∑ÇÈñcëÂÇ»èÓïÒÇ™ä‹Ç‹ÇÍǃǢNjÇ∑ÅB
  • BSD Ç©ÇÁå©ÇÍÇŒÅAClassic ÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕÇ∑Ç◊ǃÅA1 ǬÇÃÉvÉçÉZÉXÇÃíÜÇ≈é¿çsÇ≥ÇÍÇ‹Ç∑ÅB
  • DZÇà sysctl ÇåƒÇ—èoÇ∑ÇΩÇflÇ…ì¡ï Ç»å†å¿ÇÕïKóvdžÇËÇ‹ÇπÇÒÅBÇ∑Ç◊ǃÇÃÉÜÅ[ÉUÇ™ÅAÉVÉXÉeÉÄè„ÇÃÇ∑Ç◊ǃÇÃÉvÉçÉZÉXÇÃÉäÉXÉgÇéÊìæÇ≈Ç´Ç‹Ç∑ÅB
  • UNIX Programming FAQ Ç…ÇÕÅADZÇÍÇçsǧÇΩÇflÇÃÇ¢Ç≠ǬǩÇÃï˚ñ@Ç™é¶Ç≥ÇÍǃǢNjÇ∑ÅBDZÇÃíÜÇ≈ Mac OS X è„Ç≈óLå¯Ç»óBàÍÇÃï˚ñ@ÇÕÅAps ÉRÉ}ÉìÉhÉâÉCÉìÉcÅ[ÉãÇ exec ǵǃé¿çsÇ∑ÇÈï˚ñ@Ç≈Ç∑ÅBps Ç exec Ç∑ÇÈèÍçáÇ…ÇÕÅAÉcÅ[ÉãÇÃèoóÕÇÃâêÕÇ™ïKóvÇΔÇ»ÇËÅAÉäÉXÉg 1 ÇŸÇ«å¯ó¶ìIÇ…ÇÕÉVÉXÉeÉÄÉäÉ\Å[ÉXégópǵNjÇπÇÒÅB

"Processes.h" ÇÃíÜÇ≈êÈåæÇ≥ÇÍǃǢÇÈ GetProcessPID ÉãÅ[É`ÉìÇΔ GetProcessForPID ÉãÅ[É`ÉìÇégǶnjÅABSD ÉvÉçÉZÉX ID ÇΔÉvÉçÉZÉXÇÃÉVÉäÉAÉãî‘çÜÇΔÇëŒâûÇ≥ÇπÇÈDZÇΔÇ™Ç≈Ç´Ç‹Ç∑ÅB

#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/sysctl.h>

typedef struct kinfo_proc kinfo_proc;

static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount)
    // ÉVÉXÉeÉÄè„ÇÃÇ∑Ç◊ǃÇà BSD ÉvÉçÉZÉXÇÃÉäÉXÉgÇï‘Ç∑
    // DZÇÃÉãÅ[É`ÉìÇÕÅADZÇÃÉäÉXÉgÇÃäÑÇËìñǃÇçsǡǃ *procList Ç…ì¸ÇÍ
    // ÉGÉìÉgÉäÇÃêîÇ *procCount Ç…ï‘Ç∑
    // DZÇÃÉäÉXÉgÇÕé©ï™Ç≈âï˙ÇµÇ»ÇØÇÍnjǻÇÁǻǢÅiSystem ÉtÉåÅ[ÉÄÉèÅ[ÉNÇà free ÇégópÅj
    // ê¨å˜éûÅAä÷êîÇÕ 0 Çï‘Ç∑
    // ÉGÉâÅ[î≠ê∂éûÇ…ÇÕÅAä÷êîÇÕ BSD Çà errno ÇÃílÇï‘Ç∑
{
    int                 err;
    kinfo_proc *        result;
    bool                done;
    static const int    name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
    // name Ç const ÇΔǵǃêÈåæÇ∑ÇÈÇÃÇ≈ÅAsysctl Ç…ìnÇ∑ÇΔÇ´Ç…ÉLÉÉÉXÉgÇ∑ÇÈïKóvǙdžÇÈ
    // ÉvÉçÉgÉ^ÉCÉvÇ… const Ç™ä‹Ç‹ÇÍǃǢǻǢǩÇÁÇæ
    size_t              length;

    assert( procList != NULL);
    assert(*procList == NULL);
    assert(procCount != NULL);

    *procCount = 0;

    // result == NULL ÇΔ length == 0 ÇΔǵǃ sysctl ÇåƒÇ—èoÇ∑DZÇΔÇ…ÇÊÇËäJénÅB
    // DZÇÍÇÕê¨å˜ÇµÅAlength Ç™ìKêÿÇ»í∑Ç≥Ç…ê›íËÇ≥ÇÍÇÈÅB
    // ǪÇÃå„ǪÇÃÉTÉCÉYÇÃÉoÉbÉtÉ@ÇäÑÇËìñǃÅAsysctl ÇçƒÇ—åƒÇ—èoÇ∑
    // DZÇÍÇ™ê¨å˜Ç∑ÇÍÇŒèàóùÇÕèIóπÇ≈džÇÈÅBENOMEM ÉGÉâÅ[Ç≈é∏îsǵÇΩèÍçáÇÕ
    // ÉoÉbÉtÉ@Çîjä¸ÇµÇƒÉãÅ[ÉvÇ∑ÇÈïKóvǙdžÇÈÅB
    // DZÇÃÉãÅ[ÉvÇ≈ÇÕÅAçƒÇ— NULL ÇéwíËǵǃÅAsysctl ÇåƒÇ—èoÇ∑ïKóvǙdžÇÈDZÇΔÇ…íçà”ÅB
    // DZÇÍÇÕïKóvÇ»èàóùÇ≈džÇÈÅBENOMEM ÉGÉâÅ[ÇÃèÍçáÅAlength ÇÕÅA
    // ï‘Ç≥ÇÍÇÈÇ◊Ç´ÉfÅ[É^ó Ç≈ÇÕÇ»Ç≠
    // ï‘Ç≥ÇÍÇΩÉfÅ[É^ó Ç…ê›íËÇ≥ÇÍÇÈÇ©ÇÁÇæ

    result = NULL;
    done = false;
    do {
        assert(result == NULL);

        // ÉoÉbÉtÉ@Ç NULL Džǵǃ sysctl ÇåƒÇ—èoÇ∑

        length = 0;
        err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1,
                      NULL, &length,
                      NULL, 0);
        if (err == -1) {
            err = errno;
        }

        // è„ãLÇÃåƒÇ—èoǵÇÃåãâ Ç…äÓÇ√Ç´ìKêÿÇ»ÉTÉCÉYÇÃ
        // ÉoÉbÉtÉ@ÇäÑÇËìñǃÇÈ

        if (err == 0) {
            result = malloc(length);
            if (result == NULL) {
                err = ENOMEM;
            }
        }

        // DZÇÃêVǵǢÉoÉbÉtÉ@Çégǡǃ sysctl ÇçƒÇ—åƒÇ—èoÇ∑
        // ENOMEM ÉGÉâÅ[ÇéÛÇØéÊÇ¡ÇΩèÍçáÇÕÅAÉoÉbÉtÉ@Çîjä¸ÇµÇ‡Ç§àÍìxÇ‚ÇËíºÇ∑

        if (err == 0) {
            err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1,
                          result, &length,
                          NULL, 0);
            if (err == -1) {
                err = errno;
            }
            if (err == 0) {
                done = true;
            } else if (err == ENOMEM) {
                assert(result != NULL);
                free(result);
                result = NULL;
                err = 0;
            }
        }
    } while (err == 0 && ! done);

    // ÉNÉäÅ[ÉìÉiÉbÉvèàóùÇçsÇ¢ÅAéñå„èÛë‘Çê›íËÇ∑ÇÈ

    if (err != 0 && result != NULL) {
        free(result);
        result = NULL;
    }
    *procList = result;
    if (err == 0) {
        *procCount = length / sizeof(kinfo_proc);
    }

    assert( (err == 0) == (*procList != NULL) );

    return err;
}

ÉäÉXÉg 1 Ç∑Ç◊ǃÇà BSD ÉvÉçÉZÉXÇÉäÉXÉgÇ∑ÇÈÉRÅ[Éh


[2002 îN 3 åé 5 ì˙]